﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.IO;
using System.ComponentModel;

namespace EasyVideoEditor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        FFMPEGWrapper.MediaFile mediaFile;
        BackgroundWorker worker = new BackgroundWorker();
        string temp_directory;
        bool frameOn = true;

        public MainWindow()
        {
            InitializeComponent();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.WorkerReportsProgress = true;

            temp_directory = System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\AW\\EasyVideoEditor";
            if (!Directory.Exists(temp_directory))
            {
                Directory.CreateDirectory(temp_directory);
                Directory.CreateDirectory(temp_directory + "\\TempFrames");
            }
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnStart.Content = "Start";
            EnableDisableControls(true);
        }

        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            lblProgress.Content = e.ProgressPercentage.ToString() + '%';
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            StreamReader reader;
            string[] split = e.Argument.ToString().Split('\t');
            double duration = (double)TimeSpan.Parse(split[11]).TotalSeconds;
            double cTime = 0.0;
            FFMPEGWrapper.FFMPEGHelpers.PerformCropping(split[0], split[1], split[2], Int32.Parse(split[3]), Int32.Parse(split[4]), Int32.Parse(split[5]), Int32.Parse(split[6]),
                split[7], split[8],
                (int)Double.Parse(split[9]),
                (int)Double.Parse(split[10]), out reader);

            string line = "";
            string allLines = "";
            while ((line = reader.ReadLine()) != null)
            {
                allLines = allLines + '\n' + line;
                Match match2 = Regex.Match(line, @"time=([0-9]+\.?[0-9]+)");
                if (match2.Captures.Count > 0)
                {
                    cTime = (Double.Parse(match2.Groups[1].Value) / duration) * 100;
                    worker.ReportProgress((int)cTime);
                }
            }

            worker.ReportProgress(100);
        }

        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            worker.RunWorkerAsync(string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}",
                @".\FFMPEG\ffmpeg.exe", mediaFile.Path, mediaFile.Path, iudTop.Value.Value, iudBottom.Value.Value, iudLeft.Value.Value, iudRight.Value.Value,
                (string)cboVideoCodec.SelectedItem, (string)cboAudioCodec.SelectedItem,
                iudVideoBitrate.Value.Value,
                iudAudioBitrate.Value.Value, mediaFile.Duration.Value.ToString()));
            btnStart.Content = "Cancel";
            EnableDisableControls(false);
            btnStart.IsEnabled = true;
        }

        public void loadFrame(string filePath, long scrollValue)
        {
            frameOn = !frameOn;
            FFMPEGWrapper.FFMPEGHelpers.LoadFrame(@".\FFMPEG\ffmpeg.exe",
                filePath,
                String.Format("{0}\\TempFrames", temp_directory),
                new TimeSpan(scrollValue),
                frameOn);
        }

        public void loadInfo(string filePath)
        {
            mediaFile = FFMPEGWrapper.FFMPEGHelpers.getMediaInformation(@".\FFMPEG\ffmpeg.exe", filePath);
        }

        private void btnOpenVideo_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
            ofd.Filter = "Video Files (*.flv; *.avi; *.mov; *.mpg; *.mpeg; *.wmv; *.mkv; *.mp4; *.mpeg4)|*.flv; *.avi; *.mov; *.mpg; *.mpeg; *.wmv; *.mkv; *.mp4; *.mpeg4";
            if (ofd.ShowDialog() == true)
            {
                loadInfo(ofd.FileName);

                ReAnalyze(true, true);
                EnableDisableControls(true);
            }
        }

        private void EnableDisableControls(bool enable)
        {
            iudTop.IsEnabled = enable;
            iudBottom.IsEnabled = enable;
            iudLeft.IsEnabled = enable;
            iudRight.IsEnabled = enable;
            croppingControl1.IsEnabled = enable;
            btnStart.IsEnabled = enable;
            expanderAdvanced.IsEnabled = enable;
            btnAnalyze.IsEnabled = enable;
        }

        private void iudCroppingControls_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (iudTop != null && iudBottom != null && iudLeft != null && iudRight != null)
            {
                croppingControl1.CropAmount = new Thickness((double)iudLeft.Value, (double)iudTop.Value, (double)iudRight.Value, (double)iudBottom.Value);
                ReAnalyze(false, false);
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
        }

        private void btnAnalyze_Click(object sender, RoutedEventArgs e)
        {
            ReAnalyze(true, false);
        }

        private void ReAnalyze(bool includeCropping = false, bool includeAllAdvancedOverride = false)
        {
            if (mediaFile != null)
            {
                if (includeCropping)
                {
                    //loadFrame(mediaFile.Path, 0);
                    if (Directory.GetFiles(String.Format("{0}\\TempFrames", temp_directory)).Length > 0)
                    {
                        croppingControl1.Source = new BitmapImage(new Uri(String.Format("{0}\\TempFrames\\output_frame_{1}.bmp", temp_directory, frameOn ? "A" : "B"))).Clone();
                        var cropping = ImageAnalysisLib.ImageAnalysisHelpers.GetImageBorderAnalysis(String.Format("{0}\\TempFrames\\output_frame_{1}.bmp", temp_directory, frameOn ? "A" : "B"));
                        iudTop.Value = (int)cropping.Top;
                        iudBottom.Value = (int)cropping.Bottom;
                        iudLeft.Value = (int)cropping.Left;
                        iudRight.Value = (int)cropping.Right;
                        croppingControl1.CropAmount = new Thickness((double)iudLeft.Value, (double)iudTop.Value, (double)iudRight.Value, (double)iudBottom.Value);
                    }
                }

                if (sliderFramePick != null)
                {
                    sliderFramePick.Minimum = 0;
                    sliderFramePick.Maximum = mediaFile.Duration.Value.Ticks;
                }

                if (cb_rec_AudioBitrate != null && iudAudioBitrate != null && (cb_rec_AudioBitrate.IsChecked == true || includeAllAdvancedOverride))
                {
                    iudAudioBitrate.Value = mediaFile.AudioBitrate;
                }
                if (cb_rec_VideoBitrate != null && iudVideoBitrate != null && (cb_rec_VideoBitrate.IsChecked == true || includeAllAdvancedOverride))
                {
                    iudVideoBitrate.Value = (int)(((((double)mediaFile.HorizontalResolution.Value - (double)iudLeft.Value.Value - (double)iudRight.Value.Value) * ((double)mediaFile.VerticalResolution.Value - (double)iudTop.Value.Value - (double)iudBottom.Value.Value)) / ((double)mediaFile.HorizontalResolution.Value * (double)mediaFile.VerticalResolution.Value)) * ((double)mediaFile.VideoBitrate.Value - (double)mediaFile.AudioBitrate.Value));
                }
                if (cb_rec_AudioCodec != null && cboAudioCodec != null && (cb_rec_AudioCodec.IsChecked == true || includeAllAdvancedOverride))
                {
                    cboAudioCodec.SelectedItem = mediaFile.AudioCodec;
                }
                if (cb_rec_VideoCodec != null && cboVideoCodec != null && (cb_rec_VideoCodec.IsChecked == true || includeAllAdvancedOverride))
                {
                    cboVideoCodec.SelectedItem = mediaFile.VideoCodec;
                }
            }
        }

        private void AdvancedSettingsCheckBoxes_Checked(object sender, RoutedEventArgs e)
        {
            if (mediaFile != null && !String.IsNullOrEmpty(mediaFile.Path))
            {
                ReAnalyze();
            }
        }

        private void croppingControl1_CroppingChanged(object sender, Thickness NewCropValues)
        {
            //changeType = true;
            iudLeft.Value = (int)NewCropValues.Left;
            iudRight.Value = (int)NewCropValues.Right;
            iudTop.Value = (int)NewCropValues.Top;
        }

        private void sliderFramePick_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
                
        }

        private void sliderFramePick_StylusButtonUp(object sender, StylusButtonEventArgs e)
        {
            
        }

        private void sliderFramePick_MouseUp(object sender, MouseButtonEventArgs e)
        {
                //loadFrame(mediaFile.Path, (long)sliderFramePick.Value);
                //ReAnalyze(true, false);
        }

        private void sliderFramePick_PreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
            loadFrame(mediaFile.Path, (long)sliderFramePick.Value);
            ReAnalyze(true, false);
        }

        #region Help Button
        private void mniDocs_Click(object sender, RoutedEventArgs e)
        {
            Process.Start("http://easyvideocropper.codeplex.com/documentation");
        }
        #endregion

        private void mniWebsite_Click(object sender, RoutedEventArgs e)
        {
            Process.Start("http://easyvideocropper.codeplex.com/");
        }

        private void mniAbout_Click(object sender, RoutedEventArgs e)
        {
            AboutWindow win = new AboutWindow();
            win.Owner = this;
            win.ShowDialog();
        }
    }
}
